#!/usr/bin/env -S node  # 执行及构建入口(引入)
const $=global.$=new Proxy({VER:'0.0.1'},{
	get(m, k){
		let U=undefined; if(m[k]!==U) return m[k];
		let n = k.replace(/^_+/,'').split('_')[0];
		if(m[n]!==U) return U; let v=ESX.__src(n);
		if(!v) return U;  let T=v.tar, A=T.run;
		if(A){ require(v.src); return m[k]; }
		let tar='usable.tar: '+Object.keys(T);
		$.err(`$.${k}.unusable`, tar, {fix:1});
	},
});

//#!************************* [配置]默认及内置
const GEN = global.GEN = {
	// 自定配置: 首字符=小写字母
	apiBase:'/_api', // 接口host及路径前缀  SSR时:host必需
	upxBack:'/_upx', // 上传文件回显host及路径前缀

	// 构建配置: 首字母=_
	_tit:'esx', // string 应用或网站标题
	_ver:'0.0.1', // string 应用版本号 非$.VER

	// 目标配置: 首字母=$,全小写
	$run:{},

	// 子包配置:
	$SUB:{},

	// 环境配置:
	$ENV:{},

	// 内置定义: 全字母,全大写
	BLD:null, // object|null 构建执行过程  null:终端脚本执行
	RUN:true,

};

//#!************************* [导出]开发及构建
const ESX = module.exports = global.ESX = {
	ROOT: __dirname+require('node:path').sep,
	TARS: {
		run:__dirname+'/@builds/targets/run.js',//终端脚本执行
		web:__dirname+'/@builds/targets/web.js',//浏览器WEB/H5
		crx:__dirname+'/@builds/targets/crx.js',//chrome插件
		wxm:__dirname+'/@builds/targets/wxm.js',//微信小程序
		ali:__dirname+'/@builds/targets/ali.js',//支付宝小程序
	},
	/**
	 * [内部]取得代码信息:@script
	 * @param k string 方法名  $[k]
	 * @param t boolean 是否需要代码  返回含:txt
	 * @return Promise|json|mill  Promise:t=true
	 * 		返回JSON: {via, src, fix, tar, ?txt}
	 * 		via: string 相对@script路径, 无后缀
	 * 		src: string
	 */
	__src(k, t=false){
		const $FS=require('node:fs'), DIR=ESX.ROOT+'/@script/';
		const RD=/^[a-z][a-z\d]+$/, RF=/^[a-z][a-z\d]+\.js$/;
		const OPT={withFileTypes:true}, TA={}, M={};
		Object.keys(ESX.TARS).forEach(k=>TA[k]=true);
		const TAR=require(DIR+'/.tar.js'), MAP=p=>{
			$FS.readdirSync(DIR+p,OPT).forEach(v=>{
				const isDir=v.isDirectory(), n=v.name, m=p+n;
				if(isDir) return RD.test(n) && MAP(m+'/');
				if(m.indexOf('/')<0 || !RF.test(n)) return;
				let via=m.slice(0,-3), k=via, src=DIR+m;
				if(k.slice(-4)==='/aac') k = k.slice(0, -4);
				else if(k.slice(0,4)==='aac/') k=k.slice(4);
				k=k.replace(/\/(.)/g,(x,a)=>a.toUpperCase());
				M[k]={via,src,fix:[src,1,1],tar:TAR[k]||TA};
			});
		};
		const TXT = async function(k){
			let m=M[k]; if(!m) return null; let v=m.txt;
			if(v) return (v instanceof Promise) ? v : m;
			const readBack = v=>{ m.txt=v; return m; };
			return m.txt=$.fsRead(m.src).then(readBack);
		};
		ESX.__src=(k,t=false)=>t?TXT(k):(M[k]||null);
		MAP('');  return ESX.__src(k,t);
	}
};

//#!************************* [内部]运行初始化
const $M = require('node:module').prototype;
const RE = (x,k,v)=>`const ${k}= require(${v})`;
const F=/import(\s+\S+\s+)from(\s+['"]\S+?["'])/g;
let T=/(^|\n)export\s+default\s+/g, C=$M._compile;
$M._compile=function(v, p){ // ESM转CJS(有限支持)
	v = v.replace(T, '$1module.exports=');
	return C.call(this, v.replace(F,RE), p);
};
